-- table_ = {newId[int], newType[int/nil], needStack[bool/nil], trashChance[int/nil], trashId[int/nil], effect[int/nil], desc[bool/string/nil]}
--- description

function crafting(cid, item, fromPosition, itemEx, toPosition, table_)
	if type(table_) ~= 'table' or (not table_.newId) then
		return false
	end
	table_.trashChance = (table_.trashChance == nil) and 0 or table_.trashChance
	table_.newType = (table_.newType == nil) and 1 or table_.newType
	if table_.needStack and toPosition.x == CONTAINER_POSITION then
		doPlayerSendCancel(cid, "Sorry, not possible.")
		return false
	end
	if math.random(1, 100) <= table_.trashChance then
		if table_.trashId ~= nil and table_.trashId ~= 0 then
			doTransformItem(itemEx.uid, table_.trashId)
		else    ---    if table_.trashId == 0 then remove itemEx
			doRemoveItem(itemEx.uid)
		end
		doSendMagicEffect(((toPosition.x ~= CONTAINER_POSITION) and toPosition or getCreaturePosition(cid)), CONST_ME_POFF)
	else
		doTransformItem(itemEx.uid, table_.newId, table_.newType)
--------------------------------------------- ---------------------------------------------
		
			local descr = table_.desc == true and string.gsub('Item maked by |NAME|.', '|NAME|', getCreatureName(cid)) or (type(table_.desc) == "string") and table_.desc or nil
					--- getItemAttribute(uid, key), doItemSetAttribute(uid, key, value)
			if descr ~= nil then
				doSetItemSpecialDescription(itemEx.uid, descr)
			end
		
--------------------------------------------- ---------------------------------------------
		if table_.effect then
			doSendMagicEffect(((toPosition.x ~= CONTAINER_POSITION) and toPosition or getCreaturePosition(cid)), table_.effect)
		end
	end
	return true
end

function recipe(cid, item, fromPosition, itemEx, toPosition, recipeTable_)
	--- zadeklaruj zmienne
	--- sprawdz tabele
	local tempTable, removeTable = {}, {}
	
	if not (toPosition.x ~= CONTAINER_POSITION and (getThingFromPos({x = toPosition.x, y = toPosition.y, z = toPosition.z, stackpos = 2}).uid ~= 0) and (hasProperty(getThingFromPos({x = toPosition.x, y = toPosition.y, z = toPosition.z, stackpos = 2}).uid, CONST_PROP_MOVEABLE))) then
		return false
	end
	
	--- sprawdzanie 10 pierwszych elementow na podlozu
	for i = 1, 10 do 
		local tempItem = getThingFromPos({x = toPosition.x, y = toPosition.y, z = toPosition.z, stackpos = i})
		local table_count_info = tempTable[tempItem.itemid]
		
		--- czy element istnieje i da sie go przesunac
		if tempItem.uid == 0 or (not hasProperty(tempItem.uid, CONST_PROP_MOVEABLE)) then
			break
		end
		
		--- dodawanie do tabeli elementow do usuniecia poza pierwszym, ktory ma byc zmieniony
		if tempItem.uid ~= itemEx.uid then
			table.insert(removeTable, tempItem.uid)
		end
		
		--- zapis ilosci itemow danego typu do tabeli
		if table_count_info == nil then
			table.insert(tempTable, tempItem.itemid, (tempItem.type ~= 0 and tempItem.type or 1))
		else
			table.insert(tempTable, tempItem.itemid, table_count_info +(tempItem.type ~= 0 and tempItem.type or 1))
		end
	end
	
	--- jesli nie ma przedmiotow nie ma przepisu
	if table.maxn(tempTable) == 0 then
		return false
	end
	
	
	for j, table_c in pairs(recipeTable_) do --- sam przepis
		local recipeMemory = true
		
		--- sprawdzanie po kolei, czy wszystkie itemy z ziemi naleza do przepisu (tylo itemy z ziemi)
		for i, count2 in pairs(table_c.components) do --- kazdy element
			--- brak przedmiotu lub niezgadza sie ilosc
			if tempTable[i] == nil or tempTable[i] ~= count2 then
				recipeMemory = false
				break
			end
		end
		
		if recipeMemory then
			--- sprawdzanie po kolei, czy wszystkie itemy z przepisu naleza do tabeli itemow z ziemi (tylo itemy z przepisu)
			for i, n in pairs(tempTable) do
				if table_c.components[i] == nil or table_c.components[i] ~= n then
					recipeMemory = false
					break
				end
			end
			
			--- wszystko sie zgadza
			if recipeMemory then
				for xex, xec in ipairs(removeTable) do
					doRemoveItem(xec)
				end
				return crafting(cid, item, fromPosition, itemEx, toPosition, table_c)
			end
		end
	end
	
	return false
end